package com.mbg17.utils;

import com.jayway.jsonpath.DocumentContext;
import com.jayway.jsonpath.JsonPath;
import com.mbg17.domain.ApiTestInputDto;
import com.mbg17.domain.Datas;
import io.restassured.response.Response;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONObject;
import org.json.XML;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class StringUtils {
    public static String processTemplate(String template, RedisTemplate<String,Object> redisTemplate, Integer taskId){
        while (true) {
            Matcher m = Pattern.compile("\\\"##(.*?)##\\\"").matcher(template);
            if(!m.find()){
                break;
            }
            String param = m.group();
            Object invoke = null;
            // 先尝试从redis提取参数化
            if(redisTemplate!=null && redisTemplate.opsForHash().hasKey(taskId.toString(),m.group(1))){
                log.info("正在对任务({})从redis进行变量提取,提取的键为:({})",taskId,m.group(1));
                invoke = redisTemplate.opsForHash().get(String.valueOf(taskId),m.group(1));
            }else {
            // 在尝试从用工具类参数化
                log.info("正在对任务({})从工具类进行变量提取,提取的键为:({})",taskId,m.group(1));
                try {
                    invoke = FakeUtil.class.getMethod("get" + m.group(1)).invoke(null).toString();
                }catch (Exception e){
                    log.error("参数提取失败");
                    break;
                }
            }
            log.info("提取成功值为：({})",invoke);
            // 如果是字符串类型，就转成字符串
            if(invoke instanceof String){
                invoke = "\""+invoke.toString()+"\"";
            }
            template= template.replaceAll(param, invoke==null?"":invoke.toString());
        }
        return template;
    }

    public static ApiTestInputDto processTemplate(ApiTestInputDto apiTestInputDto,RedisTemplate<String,Object> redisTemplate,Integer taskRecordId){
        apiTestInputDto.setJson(StringUtils.processTemplate(apiTestInputDto.getJson(),redisTemplate,taskRecordId));
        for (Datas anAssert : apiTestInputDto.getAsserts()) {
            anAssert.setValue(StringUtils.processTemplate(anAssert.getValue(),redisTemplate,taskRecordId));
        }
        for (Datas anAssert : apiTestInputDto.getHeaders()) {
            anAssert.setValue(StringUtils.processTemplate(anAssert.getValue(),redisTemplate,taskRecordId));
        }
        for (Datas anAssert : apiTestInputDto.getUrlencodeds()) {
            anAssert.setValue(StringUtils.processTemplate(anAssert.getValue(),redisTemplate,taskRecordId));
        }
        for (Datas anAssert : apiTestInputDto.getParams()) {
            anAssert.setValue(StringUtils.processTemplate(anAssert.getValue(),redisTemplate,taskRecordId));
        }
        return apiTestInputDto;
    }

    public static void cacheParams(Response response, ApiTestInputDto apiTestInputDto, RedisTemplate<String,Object> redisTemplate, Integer taskRecordId, DocumentContext parse){
        for (Datas datas : apiTestInputDto.getExtracts()) {
            log.info("正在对任务({})进行变量存储,键为:({}),提取路径为:({})",taskRecordId,datas.getKey(),datas.getValue());
            try {
                Object read = parse.read(datas.getValue());
                redisTemplate.opsForHash().put(String.valueOf(taskRecordId), datas.getKey(), read);
            }catch (Exception e){
                log.info("任务({}),路径({})提取失败",taskRecordId,datas.getValue());
            }
        }
    }

    public static String xmlToJson(String xml){
        try {
            JSONObject jsonObj = XML.toJSONObject(xml);
            return jsonObj.toString(4);
        }catch (Exception e){
            return xml;
        }
    }
    public static void main(String[] args) {
        System.out.println(processTemplate("您好####，晚上好！您目前余额：##Phone##元，积分：##Name##",null,104));
        String XML_STRING =
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
                        "<root>" +
                        "<firstName>John</firstName>" +
                        "<lastName>Snow</lastName>" +
                        "<age>25</age>" +
                        "<spouse/>" +
                        "<address>" +
                        "<street>237 Harrison Street</street>" +
                        "<city>Brooklyn, NY</city>" +
                        "<state>New York</state>" +
                        "<postalCode>11238</postalCode>" +
                        "</address>" +
                        "<phoneNumbers>" +
                        "<type>mobile</type>" +
                        "<number>212 555-3346</number>" +
                        "</phoneNumbers>" +
                        "<phoneNumbers>" +
                        "<type>fax</type>" +
                        "<number>646 555-4567</number>" +
                        "</phoneNumbers>" +
                        "</root>";
        System.out.println(xmlToJson(XML_STRING));
    }
}
